<?php
use Scshux\Mvc\UrlResolver;
use Phalcon\Di\FactoryDefault;
/**
 * 引导文件
 *
 * @category     Shuxun Cms
 * @date         2015年10月18日
 * @author       Shuxun Team <kaiping.jiang@scshux.com>
 * @file         Application.php
 */
define('DS', DIRECTORY_SEPARATOR);
define('PS', PATH_SEPARATOR);
if(!defined('APPLICATION_PATH')){
	define('APPLICATION_PATH', dirname(__FILE__));
}
include_once APPLICATION_PATH.'/core/Scshux/functions.php';
class Application extends \Phalcon\Mvc\Application
{
	/**
	 * di
	 * @var \Phalcon\DI\FactoryDefault
	 */
	protected $di = null;

	protected $config = null;

	/**
	 * 构造函数
	 */
	public  function __construct()
	{

		@ini_set('memory_limit',          '68M');

		if(!file_exists(APPLICATION_PATH.'/etc/config.php')){
		    $errorMsg = 'Please initialize config file!';
		    die($errorMsg);
		}

		$configData = include_once APPLICATION_PATH.'/etc/config.php';
		$config = new \Phalcon\Config($configData);

		$this->config = $config;

		//设置时区
		//set default timezone
		$config->timezone = isset($config->timezone)? $config->timezone : 'PRC';
		date_default_timezone_set($config->timezone);

		//di
		$this->di = new \Phalcon\DI\FactoryDefault();

		$this->_initLoader($config);
		$this->_initDebug($config);
		$this->_initCore($config);
		$this->_initCache($config);
		$this->_initSession($config);
		$this->_initDB($config);
		$this->_initUrl($config);
		$this->_initView($config);
		$this->_initOther($config);

		parent::__construct($this->di);

	}

	/**
	 * 运行程序
	 */
	public function  run()
	{
		try {

			$this->registerModules(array(
				'backend' => array(
					'className' => 'Scshux\Backend\Module',
					'path' => APPLICATION_PATH . '/modules/backend/Module.php'
				),
				'front' => array(
						'className' => 'Scshux\Front\Module',
						'path' => APPLICATION_PATH . '/modules/front/Module.php'
				)
			));
			$this->setDefaultModule('front');
			echo $this->handle()->getContent();

		} catch (\Exception $e) {
			echo $e->getMessage();
			exit;
		}
	}

	/**
	 * 系统错误输出
	 * @param number $errno
	 * @param number $errstr
	 * @param number $errfile
	 * @param number $errline
	 * @return multitype:
	 */
	public static function customerErrorHandler($errno=0 ,$errstr=0 , $errfile=0 ,$errline=0){


		$logPath = APPLICATION_PATH .'/var/errorLog/';
		if(!file_exists($logPath)){
			mkdir($logPath,0777,true);
		}
		if($errno && $errfile){ //普通错误

			if($errno == 8) return  array();
			if($errno == 2) return  array();

			$earr = array();
			$earr['type'] = $errno;
			$earr['message'] = $errstr;
			$earr['file'] = $errfile;
			$earr['line'] = $errline;
		}else{ //shutdown

			$earr = error_get_last();
			//记录sql日志
			$profiles = FactoryDefault::getDefault()->get('profiler')->getProfiles();
			if($profiles){
				//遍历输出
				$sqlLog = '';
				foreach ($profiles as $profile) {
					$sqlLog .= "SQL语句: " . $profile->getSQLStatement() .PHP_EOL;
					//$sqlLog .=  "开始时间: " . $profile->getInitialTime()  .PHP_EOL;
					//$sqlLog .=  "结束时间: " . $profile->getFinalTime() .PHP_EOL;
					$sqlLog .=  "消耗时间: " . $profile->getTotalElapsedSeconds().PHP_EOL.PHP_EOL;
				}
				file_put_contents($logPath.'/'.date('Y-m-d').'.error', $sqlLog.PHP_EOL,FILE_APPEND);
			}
		}

		if($earr){
			file_put_contents($logPath.'/'.date('Y-m-d').'.error', var_export($earr,true).PHP_EOL.PHP_EOL,FILE_APPEND);
		}
		return array();
	}


	/**
	 * 初始化全局加载器
	 */
	protected  function _initLoader($config)
	{
		$loader = new \Phalcon\Loader();
		$loader->registerDirs(
				array(
						APPLICATION_PATH.'/core'
				)
		);
		$loader->register();

	}

	/**
	 * 初始化session
	 * @param  $config
	 */
	protected  function _initSession($config)
	{
		if (!isset($config->session)) {
			$session = new \Phalcon\Session\Adapter\Files();
		} else {
			$adapterClass = 'Phalcon\Session\Adapter\\' . $config->session->adapter;
			$options = (array)$config->session->options;
			$session = new $adapterClass($options);
		}
		$session->start();
		$this->di->setShared('session', $session);
		return $session;

	}

	/**
	 * 初始化 cache
	 * @param  $config
	 */
	protected  function _initCache($config)
	{
		$this->di->set('cache', function() use ($config){

			if (!isset($config->cache->lifetime)){
				$config->cache->lifetime = 3600;
			}

			//默认缓存时间为一天
			$frontCache = new \Phalcon\Cache\Frontend\Data(array(
					"lifetime" => $config->cache->lifetime
			));

			if (isset($config->cache->options->cacheDir)){
				if(!file_exists($config->cache->options->cacheDir)){
					@mkdir($config->cache->options->cacheDir,0777,true);
				}
			}

			$adapterClass = '\Phalcon\Cache\Backend\\' . $config->cache->adapter;
			$options = (array)$config->cache->options;
			$cache = new $adapterClass($frontCache,$options);
			return $cache;

		});
	}


	/**
	 * 初始化数据库
	 */
	protected  function _initDB($config)
	{
		$this->di->set('db', function() use ($config){

			$connection = new \Phalcon\Db\Adapter\Pdo\Mysql(array(
					"host"     => $config->database->host,
					"username" => $config->database->username,
					"password" => $config->database->password,
					"dbname"   => $config->database->dbname,
					'charset'  => $config->database->charset,
					'port'	   => $config->database->port
			));

			if(!empty($config->debug)){
				//新建一个事件管理器
				$eventsManager = new \Phalcon\Events\Manager();
				//从di中获取共享的profiler实例

				$profiler = FactoryDefault::getDefault()->getProfiler();

				//监听所有的db事件
				$eventsManager->attach('db', function($event, $connection) use ($profiler) {
					//一条语句查询之前事件，profiler开始记录sql语句
					if ($event->getType() == 'beforeQuery') {
						$profiler->startProfile($connection->getSQLStatement());
					}
					//一条语句查询结束，结束本次记录，记录结果会保存在profiler对象中
					if ($event->getType() == 'afterQuery') {
						$profiler->stopProfile();
					}
				});
				//将事件管理器绑定到db实例中
				$connection->setEventsManager($eventsManager);
			}
			return $connection;
		},true);

	}


	/**
	 * 初始化视图
	 */
	protected  function _initView($config)
	{

		$this->di->set('view', function () use ($config) {

			$view = new \Scshux\Mvc\View\SmartyView();


			//普通模板
			$phtml = new \Phalcon\Mvc\View\Engine\Php($view);

			include_once APPLICATION_PATH.'/libraries/Smarty/Smarty.class.php';

			if(!file_exists(APPLICATION_PATH.'/var/compile_dir/')){
				mkdir(APPLICATION_PATH.'/var/compile_dir/',0777,true);
			}

			if(!file_exists(APPLICATION_PATH.'/var/cache_dir/')){
				mkdir(APPLICATION_PATH.'/var/cache_dir/',0777,true);
			}

			$smarty = new \Smarty();
			$smarty->left_delimiter='<{';
			$smarty->right_delimiter='}>';
			$smarty->compile_dir = APPLICATION_PATH.'/var/compile_dir/';
			$smarty->cache_dir = APPLICATION_PATH.'/var/cache_dir/';
			$tpl   = new \Scshux\Mvc\View\Engine\Smarty($view);
			$tpl->setSmarty($smarty);

			$viewEngines = [
					".htm"  => $tpl,
					".phtml" => $phtml,
			];

			$view->registerEngines($viewEngines);
			return $view;

		}, true);
	}


	/**
	 * 初始化内核
	 */
	protected  function _initCore($config)
	{
		$this->di->set('core', function() use($config){
			return new \Scshux\Plugin\Core();
		});
	}

	/**
	 * 配置url
	 * @param  $config
	 * @return \Phalcon\Mvc\Url
	 */
	protected  function  _initUrl($config)
	{
		$this->di->set('url', function () use ($config) {
			$url = new  UrlResolver();
			if(!strpos($config->baseUrl, '://')){
				$serverHost = $_SERVER['HTTP_HOST'];
				if(isset($_SERVER['HTTP_X_FORWARDED_HOST'])){
					$serverHost = $_SERVER['HTTP_X_FORWARDED_HOST'];
				}
				$config->baseUrl = 'http://'.$serverHost.$config->baseUrl;
			}
			$url->setBaseUri($config->baseUrl);
			return $url;
		});


		if(!isset($config->adminPath)){
			$config->adminPath = 'admin';
		}

		$this->di->set('router', function() use($config){

			$router = new \Phalcon\Mvc\Router();
			$router->setDefaultModule('front');
			$router->add('/'.$config->adminPath,array(
					'module' => 'backend',
					'controller' => 'index',
					'action' => 'index'
			));
			$router->add('/'.$config->adminPath.'/?([a-zA-Z0-9_-]*)/?([a-zA-Z0-9_]*)(/.*)*',array(
					'module' => 'backend',
					'controller' => 1,
					'action' => 2,
					'params' => 3
			));
			return $router;

		});


	}


	/**
	 * 初始化其它数据
	 */
	protected  function  _initOther($config)
	{
    	$this->di->set('config',function () use ($config) {
			return $config;
		},true);

    	//注册监控
    	$this->di->set('profiler', function(){
    		return new \Phalcon\Db\Profiler();
    	}, true);

    	//注册日志管理
        $this->di->set('logger', function () use ($config) {
			$logger = new Phalcon\Logger\Adapter\File($config->logger->path .'system.log');
			if($config->logger->format){
				$formatter = new \Phalcon\Logger\Formatter\Line(($format ? $format : $config->logger->format));
				$logger->setFormatter($formatter);
			}
			return $logger;
		});

        $this->di->set('crypt', function () use ($config) {
        		$crypt = new \Phalcon\Crypt();
        		$crypt->setKey($config->cryptKey);
        		return $crypt;
        });


        $this->di->set('cookies', function () {
        		$cookies = new \Phalcon\Http\Response\Cookies();
        		$cookies->useEncryption(true);
        		return $cookies;
        });


	}

	/**
	 * 初始化调试
	 */
	protected  function  _initDebug($config)
	{

		if(empty($config->debug)) return ;

		$err = 'Application::customerErrorHandler';
		register_shutdown_function($err) OR set_error_handler($err,E_ALL); // 同时注册两个函数.

	}

}